feat(workbench): effect-atom phase-1 pilot — Agent Document panel on @effect/atom-react under a root RegistryProvider (#105) - #250
Conversation
…ct atoms under a root RegistryProvider (#105 phase 1) Replaces RuntimeDocumentPanel's hand-rolled request union, AbortController, and stale-run guards with an Atom.family keyed by run id consuming the existing strictly-decoded agent-document-client output. Adds the Workbench browser-state convention to docs/effect-conventions.md, a disposal regression test (mount/unmount cycles interrupt in-flight loads and leak no subscriptions), and exact pins effect@4.0.0-rc.112 / @effect/atom-react@4.0.0-rc.112 / scheduler@0.27.0.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
🦋 Changeset detectedLatest commit: 34a1216 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 34a12163ae
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| export const agentDocumentLoaderAtom = Atom.make<AgentDocumentLoader | undefined>(undefined); | ||
|
|
||
| export const agentDocumentEventsAtom = Atom.family((runId: string) => Atom.make((get) => { | ||
| const loader = get.once(agentDocumentLoaderAtom); |
There was a problem hiding this comment.
Invalidate document atoms when the loader changes
When a mounted RuntimeInspector receives a replacement loadDocumentEvents callback while displaying the same run, useAgentDocumentLoader updates the loader atom, but get.once establishes no dependency and the family is keyed only by runId. Because loaderReady also remains true whenever any previous loader exists, the result atom stays mounted and continues using the old client/request or cached result indefinitely; this regresses the previous effect, which reloaded whenever loadDocumentEvents changed. Include the loader identity in the atom lifecycle or unmount/refresh the result atom during loader replacement.
Useful? React with 👍 / 👎.
Summary
Phase 1 of the effect-atom pilot for the Workbench (#105), per the completed evaluation.
RegistryProviderin the Workbench app shell (main.tsx); the module-level default registry is never used.RuntimeDocumentPanel's hand-rolled request state (manual request union,AbortController, stale-run guards) to anAtom.familykeyed by run id in a dedicated browser-state module (src/runtime/agent-document-atoms.ts). Atoms consume the existing strictly-decodedagent-document-client.tsoutput; the zod decoders andProjectClient/RuntimeClientlifecycles are untouched.Effect.tryPromisemaps fiber interruption to the requestAbortSignal, so unmount/dispose aborts in-flight loads structurally.effect@4.0.0-rc.112,@effect/atom-react@4.0.0-rc.112,scheduler@0.27.0. No legacy@effect-atom/*packages. No stream-backed derived atoms (rc.112 disposal bug — fixed upstream post-rc.112, unpublished).docs/effect-conventions.md(incl. the unstable-module adoption row and re-pin lockstep steps).runtime-document-atoms-disposal.test.ts, integration pool): 5 mount/unmount cycles with a never-resolving loader assert one abort per unmount; 5 resolving cycles assert re-render and bounded loader calls; zero page errors.agent-bundle(the Workbench dist ships inside the published package).Bundle (workbench production build, rsbuild size table)
The cost is the
effectcore + atom runtime entering the shared chunk (816.js 505.0 kB → 584.js 617.9 kB).Test plan
pnpm typecheckandpnpm lint(0 errors/warnings)pnpm test:unit(2330 passed, 0 failed)runtime-inspector.test.ts+ newruntime-document-atoms-disposal.test.ts(production bundle + real Chrome)runtime-playground.e2e.test.ts(populated Document + decode-diagnostic flows) andoverview.e2e.test.ts(populated + stale-diagnostic/repair flows) — 16/16 passedOut of scope (phases 2–5, recorded on #105)
Route-editor state, project/capability graph, logs/evals stream pages, MCP controller.